<template>
  <div class="filter-wrapper">
    <el-form
      ref="FormRef"
      :model="form"
      :label-position="(attrs.labelPosition as 'left' | 'right' | 'top') ?? 'left'"
      class="filter-form"
      :class="[`flex-${columnNum}`]"
    >
      <el-form-item
        v-for="(item, index) in handleFilters"
        v-show="isShowFilterItem(index)"
        :prop="item.prop"
        v-bind="item"
        class="filter-item"
      >
        <!-- 插槽 -->
        <slot v-if="item.slot" :name="item.slot" :form="form" :prop="getFormItemProp(item)"  :value="form[getFormItemProp(item)]" :bind="getItemBind(item)"></slot>
        <!-- 输入框 -->
        <el-input v-else-if="!item.type && typeof item.prop" v-model.trim="form[getFormItemProp(item)]" v-bind="getItemBind(item)"/>
        <!-- 数字输入框 -->
        <el-input-number v-else-if="item.type === 'input-number'" v-model="form[getFormItemProp(item)]" v-bind="getItemBind(item)"/>
        <!-- 选择器 -->
        <el-select v-else-if="item.type === 'select'" v-model="form[getFormItemProp(item)]" v-bind="getItemBind(item)">
          <el-option v-for="option in item.list" :key="option.value" :label="option.label" :value="option.value" />
        </el-select>
        <!-- 级联选择器 -->
        <el-cascader v-else-if="item.type === 'cascader'" v-model="form[getFormItemProp(item)]" :options="item.list" v-bind="getItemBind(item)"/>
        <!-- 日期选择器 -->
        <el-date-picker v-else-if="dateTypes.includes(item.type)" v-model="form[getFormItemProp(item)]" v-bind="getItemBind(item)"/>
        <!-- 日期范围选择器 -->
        <el-date-picker v-else-if="dateRangeTypes.includes(item.type)" v-model="form[getFormItemProp(item)]" v-bind="getItemBind(item)"/>
      </el-form-item>

      <div class="filter-item filter-item-btn-wrapper">
        <el-button @click="query" type="primary" :loading="loading" style="width: 80px;">
          <Icon v-show="!loading" icon="iconamoon:search-bold" style="margin-right: 5px;"/>查询</el-button>
        <el-button @click="reset">
          <Icon icon="ri:reset-left-line"  style="margin-right: 5px;"/>重置
        </el-button>
        <el-tooltip v-if="!isOneRow" placement="bottom" effect="dark" 
          :content="isShowAllByRow ? '默认显示行数过大,请调整自定义设置' : (isShowAll ? '显示部分搜索条件' : '显示所有搜索条件')"
        >
          <el-button @click="switchIsShowAll" style="padding: 0px;min-width: 35px;" :disabled="isShowAllByRow">
            <Icon :icon="isShowAll ? 'solar:double-alt-arrow-up-line-duotone' : 'solar:double-alt-arrow-down-line-duotone'" :size="26"/>
          </el-button>
        </el-tooltip>
        <el-tooltip v-if="customId && filterCustom" placement="bottom" effect="dark" content="自定义设置">
          <el-button @click="openFilterCustomView" style="padding: 0px;min-width: 35px;">
            <Icon icon="mingcute:settings-2-line" :size="20"/>
          </el-button>
        </el-tooltip>
      </div>
    </el-form>

      <!-- Table列字段自定义设置组件 -->
      <FilterCustomView
        v-if="customId && filterCustom"
        ref="FilterCustomViewRef"
        :custom-id="customId"
        :sourceFilters="filters"
        :filter-is-show-all="filterIsShowAll"
        :filter-show-row="filterShowRow"
        @update:custom-config="useCustomConfig"
    >
    </FilterCustomView>
  </div>
</template>


<script setup lang="ts" name="Filter">
  import '../style/index.scss'
  import { ref, computed, watch, useAttrs, onMounted } from "vue";
  import { ElForm, ElInput, ElInputNumber, ElSelect, ElCascader, ElDatePicker, ElButton, ElTooltip } from "element-plus";
  import { FilterCustomView, FilterItem, getInitFilterForm, getFilterParam, getFormItemProp, dateTypes, dateRangeTypes, getShortcuts, FilterCustomType, getFilterCustomConfig } from '@/components'
  const attrs = useAttrs()
  const props = withDefaults(
    defineProps<{
      // 搜索条件
      filters?: FilterItem[],
      // 自定义配置的id 区别每个custom
      customId: string,
      // 是否开启搜索条件设置工具
      filterCustom?: boolean
      // 加载状态
      loading?: boolean
      // isShowAll是否展开展示所有搜索条件 默认值
      filterIsShowAll?: boolean
      // showRow展示行数 默认值
      filterShowRow?: number
    }>(),
    {
      filters: () => [],
      filterCustom: true,
      loading: false,
      filterIsShowAll: false,
      filterShowRow: 1
    }
  )
  const emit = defineEmits<{
    (e: 'query', filterParams),
    (e: 'filter-reset'),
  }>()

  const FormRef = ref<InstanceType<typeof ElForm>>()  
  const FilterCustomViewRef = ref<InstanceType<typeof FilterCustomView>>()

  // 是否展开展示所有搜索条件
  const isShowAll = ref(props.filterIsShowAll)
  // 展示行数
  const showRow = ref(props.filterShowRow)

  // 是否只有一行搜索添条件
  const isOneRow = computed(() => props.filters.length <= columnNum.value)
  // 可能不需要 isShowAll 单凭showRow便把所有搜索条件显示出来了
  const isShowAllByRow = computed(() => props.filters.length <= showRow.value * columnNum.value)


  // 一行放多少个搜索条件
  const columnNum = ref(4)
  const resizeObserver = new ResizeObserver(()=>{
    if (FormRef.value) {
      const width = FormRef.value.$el.offsetWidth
      if (width >= 1650) {
        columnNum.value = 6
      } else if (width >= 1300) {
        columnNum.value = 5
      } else if (width >= 1000) {
        columnNum.value = 4
      } else {
        columnNum.value = 3
      }
    }
  })
  onMounted(()=>{
    FormRef.value && resizeObserver.observe(FormRef.value.$el)
  })

  // 是否展示改FilterItem
  const isShowFilterItem = (index):boolean => {
    return isShowAll.value || index < showRow.value * columnNum.value
  }


  // 搜索条件参数
  const form = ref(getInitFilterForm(props.filters))

  // 处理后的Filter
  const handleFilters = ref<FilterItem[]>()

  // 获取item的bind
  const getItemBind = (item: FilterItem) => {
    const itemBind = {...item}
    // 自定义字段初始默认值[value] 和element-plus[el-input]组件冲突 需要排除
    delete itemBind.value
    delete itemBind.slot
    return itemBind
  }

  // Filters校验处理器
  const checkHandle = (item: FilterItem) => {
    // 日期范围类型  prop才可以是数据
    if (!dateRangeTypes.includes(item.type) && Array.isArray(item.prop)) {
      throw new Error(`[Filter] 日期范围类型[${item.type}]的prop才可以使用数组`)
    } else if (dateRangeTypes.includes(item.type) && (!Array.isArray(item.prop) || item.prop.length != 2)) {
      throw new Error(`[Filter] 日期范围类型[${item.type}]的prop数组必须包括开始时间和结束时间字段`)
    }
  }

  // Filters公共处理器
  const commonHandle = (item: FilterItem) => {
    // 是否显示清除按钮
    item.clearable = item.clearable ?? true
  }


  // 日期范围处理器
  const daterangeHandle = (item: FilterItem) => {
    // 范围选择时选中日期所使用的当日内默认时刻
    item.defaultTime = item.defaultTime ?? [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]
    // 快捷选项
    item.shortcuts = item.shortcuts ?? getShortcuts()
  }

  // Filters类型处理器
  const typeHandles = {
    // Selecet选择器组件
    select: (item: FilterItem) => {
      // 多选情况下
      if (item.multiple) {
        item.collapseTags = item.collapseTags ?? true
        item.collapseTagsTooltip = item.collapseTagsTooltip ?? true
      }
      // tag 标签类型
      item.tagType = 'primary'
    },
    // Cascader级联选择器
    cascader: (item: FilterItem) => {
      item.props = item.props ?? {}
      // 	次级菜单的展开方式 'click' | 'hover'
      item.props.expandTrigger = 'hover'
      // 多选情况下
      item.props.multiple = item.props.multiple ?? item.multiple
      if (item.props.multiple) {
        item.collapseTags = item.collapseTags ?? true
        item.collapseTagsTooltip = item.collapseTagsTooltip ?? true
      }
      // 在选中节点改变时，是否返回由该节点所在的各级菜单的值所组成的数组，若设置 false，则只返回该节点的值
      item.props.emitPath = item.props.emitPath ?? false
      // tag 标签类型
      item.tagType = 'primary'
      // 选项是否可以被搜索
      item.filterable = item.filterable ?? true
    },
    yearrange: daterangeHandle,
    monthrange: daterangeHandle,
    daterange: daterangeHandle,
    datetimerange: daterangeHandle
  }


  // 处理Filter
  const handleFilter = (list: FilterItem[]) => {
    // 递归TableColumn处理
    list.forEach(item => {
      // 校验
      checkHandle(item)
      // 公共处理
      commonHandle(item)
      // 根据类型进行特殊处理 无对应类型使用默认处理器
      item.type && typeHandles[item.type] ? typeHandles[item.type](item) : false
    })
    return list
  }
  
  // 使用自定义配置
  const useCustomConfig = (config:FilterCustomType) => {
    isShowAll.value = config.isShowAll
    showRow.value = config.showRow
    handleFilters.value = handleFilter(config.filters)
  }

  // 初始化
  const init = () => {
    if (props.filterCustom) {
      const config = getFilterCustomConfig(props.customId, { 
        isShowAll:props.filterIsShowAll,
        showRow: props.filterShowRow,
        filters: props.filters
      })
      useCustomConfig(config)
    } else {
      handleFilters.value = handleFilter(props.filters)
    }
  }
  init()

  watch(
    () => props.filters,
    () => {
      handleFilters.value = handleFilter(props.filters)
    },
    { deep: true }
  )


  // 查询
  const query = () => {
    emit('query', getFilterParam(handleFilters.value, form.value))
  }


  // 重置
  const reset = () => {
    form.value = getInitFilterForm(props.filters)
    emit('filter-reset')
  }

  // 切换是否展开展示所有搜索条件
  const switchIsShowAll = () => {
    isShowAll.value = !isShowAll.value
  }


  // 打开Filter搜索条件自定义设置组件
  const openFilterCustomView = () => {
    FilterCustomViewRef.value.openDialog()
  }

</script>
